home *** CD-ROM | disk | FTP | other *** search
/ Programming Windows (5th Edition) / Programming Windows, 5th ed. - Companion CD (097-0002183)(1999).iso / Chap06 / KeyView1 / KeyView1.c next >
Encoding:
C/C++ Source or Header  |  1998-10-09  |  7.0 KB  |  201 lines

  1. /*--------------------------------------------------------
  2.    KEYVIEW1.C -- Displays Keyboard and Character Messages
  3.                  (c) Charles Petzold, 1998
  4.   --------------------------------------------------------*/
  5.  
  6. #include <windows.h>
  7.  
  8. LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;
  9.  
  10. int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
  11.                     PSTR szCmdLine, int iCmdShow)
  12. {
  13.      static TCHAR szAppName[] = TEXT ("KeyView1") ;
  14.      HWND         hwnd ;
  15.      MSG          msg ;
  16.      WNDCLASS     wndclass ;
  17.      
  18.      wndclass.style         = CS_HREDRAW | CS_VREDRAW ;
  19.      wndclass.lpfnWndProc   = WndProc ;
  20.      wndclass.cbClsExtra    = 0 ;
  21.      wndclass.cbWndExtra    = 0 ;
  22.      wndclass.hInstance     = hInstance ;
  23.      wndclass.hIcon         = LoadIcon (NULL, IDI_APPLICATION) ;
  24.      wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW) ;
  25.      wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH) ;
  26.      wndclass.lpszMenuName  = NULL ;
  27.      wndclass.lpszClassName = szAppName ;
  28.  
  29.      if (!RegisterClass (&wndclass))
  30.      {
  31.           MessageBox (NULL, TEXT ("This program requires Windows NT!"), 
  32.                       szAppName, MB_ICONERROR) ;
  33.           return 0 ;
  34.      }
  35.      
  36.      hwnd = CreateWindow (szAppName, TEXT ("Keyboard Message Viewer #1"),
  37.                           WS_OVERLAPPEDWINDOW,
  38.                           CW_USEDEFAULT, CW_USEDEFAULT,
  39.                           CW_USEDEFAULT, CW_USEDEFAULT,
  40.                           NULL, NULL, hInstance, NULL) ;
  41.      
  42.      ShowWindow (hwnd, iCmdShow) ;
  43.      UpdateWindow (hwnd) ;
  44.      
  45.      while (GetMessage (&msg, NULL, 0, 0))
  46.      {
  47.           TranslateMessage (&msg) ;
  48.           DispatchMessage (&msg) ;
  49.      }
  50.      return msg.wParam ;
  51. }
  52.  
  53. LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
  54. {
  55.      static int   cxClientMax, cyClientMax, cxClient, cyClient, cxChar, cyChar ;
  56.      static int   cLinesMax, cLines ;
  57.      static PMSG  pmsg ;
  58.      static RECT  rectScroll ;
  59.      static TCHAR szTop[] = TEXT ("Message        Key       Char     ")
  60.                             TEXT ("Repeat Scan Ext ALT Prev Tran") ;
  61.      static TCHAR szUnd[] = TEXT ("_______        ___       ____     ")
  62.                             TEXT ("______ ____ ___ ___ ____ ____") ;
  63.  
  64.      static TCHAR * szFormat[2] = { 
  65.           
  66.                TEXT ("%-13s %3d %-15s%c%6u %4d %3s %3s %4s %4s"),
  67.                TEXT ("%-13s            0x%04X%1s%c %6u %4d %3s %3s %4s %4s") } ;
  68.  
  69.      static TCHAR * szYes  = TEXT ("Yes") ;
  70.      static TCHAR * szNo   = TEXT ("No") ;
  71.      static TCHAR * szDown = TEXT ("Down") ;
  72.      static TCHAR * szUp   = TEXT ("Up") ;
  73.  
  74.      static TCHAR * szMessage [] = { 
  75.                          TEXT ("WM_KEYDOWN"),    TEXT ("WM_KEYUP"), 
  76.                          TEXT ("WM_CHAR"),       TEXT ("WM_DEADCHAR"), 
  77.                          TEXT ("WM_SYSKEYDOWN"), TEXT ("WM_SYSKEYUP"), 
  78.                          TEXT ("WM_SYSCHAR"),    TEXT ("WM_SYSDEADCHAR") } ;
  79.      HDC          hdc ;
  80.      int          i, iType ;
  81.      PAINTSTRUCT  ps ;
  82.      TCHAR        szBuffer[128], szKeyName [32] ;
  83.      TEXTMETRIC   tm ;
  84.      
  85.      switch (message)
  86.      {
  87.      case WM_CREATE:
  88.      case WM_DISPLAYCHANGE:
  89.      
  90.                // Get maximum size of client area
  91.  
  92.           cxClientMax = GetSystemMetrics (SM_CXMAXIMIZED) ;
  93.           cyClientMax = GetSystemMetrics (SM_CYMAXIMIZED) ;
  94.  
  95.               // Get character size for fixed-pitch font
  96.  
  97.           hdc = GetDC (hwnd) ;
  98.  
  99.           SelectObject (hdc, GetStockObject (SYSTEM_FIXED_FONT)) ;
  100.           GetTextMetrics (hdc, &tm) ;
  101.           cxChar = tm.tmAveCharWidth ;
  102.           cyChar = tm.tmHeight ;
  103.  
  104.           ReleaseDC (hwnd, hdc) ;
  105.  
  106.                // Allocate memory for display lines
  107.  
  108.           if (pmsg)
  109.                free (pmsg) ;
  110.  
  111.           cLinesMax = cyClientMax / cyChar ;
  112.           pmsg = malloc (cLinesMax * sizeof (MSG)) ;
  113.           cLines = 0 ;
  114.                                    // fall through
  115.      case WM_SIZE:
  116.           if (message == WM_SIZE)
  117.           {
  118.                cxClient = LOWORD (lParam) ;
  119.                cyClient = HIWORD (lParam) ;
  120.           }
  121.                // Calculate scrolling rectangle
  122.  
  123.           rectScroll.left   = 0 ;
  124.           rectScroll.right  = cxClient ;
  125.           rectScroll.top    = cyChar ;
  126.           rectScroll.bottom = cyChar * (cyClient / cyChar) ;
  127.  
  128.           InvalidateRect (hwnd, NULL, TRUE) ;
  129.           return 0 ;
  130.           
  131.      case WM_KEYDOWN:
  132.      case WM_KEYUP:
  133.      case WM_CHAR:
  134.      case WM_DEADCHAR:
  135.      case WM_SYSKEYDOWN:
  136.      case WM_SYSKEYUP:
  137.      case WM_SYSCHAR:
  138.      case WM_SYSDEADCHAR: 
  139.  
  140.                // Rearrange storage array
  141.  
  142.           for (i = cLinesMax - 1 ; i > 0 ; i--)
  143.           {
  144.                pmsg[i] = pmsg[i - 1] ;
  145.           }
  146.                // Store new message
  147.  
  148.           pmsg[0].hwnd = hwnd ;
  149.           pmsg[0].message = message ;
  150.           pmsg[0].wParam = wParam ;
  151.           pmsg[0].lParam = lParam ;
  152.  
  153.           cLines = min (cLines + 1, cLinesMax) ;
  154.  
  155.                // Scroll up the display
  156.  
  157.           ScrollWindow (hwnd, 0, -cyChar, &rectScroll, &rectScroll) ;
  158.  
  159.           break ;        // ie, call DefWindowProc so Sys messages work
  160.           
  161.      case WM_PAINT:
  162.           hdc = BeginPaint (hwnd, &ps) ;
  163.  
  164.           SelectObject (hdc, GetStockObject (SYSTEM_FIXED_FONT)) ;
  165.           SetBkMode (hdc, TRANSPARENT) ;
  166.           TextOut (hdc, 0, 0, szTop, lstrlen (szTop)) ;
  167.           TextOut (hdc, 0, 0, szUnd, lstrlen (szUnd)) ;
  168.  
  169.           for (i = 0 ; i < min (cLines, cyClient / cyChar - 1) ; i++)
  170.           {
  171.                iType = pmsg[i].message == WM_CHAR ||
  172.                        pmsg[i].message == WM_SYSCHAR ||
  173.                        pmsg[i].message == WM_DEADCHAR ||
  174.                        pmsg[i].message == WM_SYSDEADCHAR ;
  175.  
  176.                GetKeyNameText (pmsg[i].lParam, szKeyName, 
  177.                                sizeof (szKeyName) / sizeof (TCHAR)) ;
  178.  
  179.                TextOut (hdc, 0, (cyClient / cyChar - 1 - i) * cyChar, szBuffer,
  180.                         wsprintf (szBuffer, szFormat [iType],
  181.                              szMessage [pmsg[i].message - WM_KEYFIRST],                   
  182.                              pmsg[i].wParam,
  183.                              (PTSTR) (iType ? TEXT (" ") : szKeyName),
  184.                              (TCHAR) (iType ? pmsg[i].wParam : ' '),
  185.                              LOWORD (pmsg[i].lParam),
  186.                              HIWORD (pmsg[i].lParam) & 0xFF,
  187.                              0x01000000 & pmsg[i].lParam ? szYes  : szNo,
  188.                              0x20000000 & pmsg[i].lParam ? szYes  : szNo,
  189.                              0x40000000 & pmsg[i].lParam ? szDown : szUp,
  190.                              0x80000000 & pmsg[i].lParam ? szUp   : szDown)) ;
  191.           }
  192.           EndPaint (hwnd, &ps) ;
  193.           return 0 ;
  194.  
  195.      case WM_DESTROY:
  196.           PostQuitMessage (0) ;
  197.           return 0 ;
  198.      }
  199.      return DefWindowProc (hwnd, message, wParam, lParam) ;
  200. }
  201.